#ifndef _HTTPCHUNKEDSTREAM_HPP_
#define _HTTPCHUNKEDSTREAM_HPP_

#include "jhdefs.hpp"
#include "net/HTTPSession.hpp"
#include "HTTPBasicStreamBuf.hpp"
#include "net/MemoryPool.hpp"

#include <istream>
#include <ostream>

NET_NAMESPACE_BEGIN

//
// CHTTPChunkedStreamBuf
//
class CHTTPChunkedStreamBuf : public HTTPBasicStreamBuf
{
public:
	typedef HTTPBasicStreamBuf::openmode openmode;

	CHTTPChunkedStreamBuf(CHTTPSession& session, openmode mode);
	~CHTTPChunkedStreamBuf();
	void close();

protected:
	int readFromDevice(char* buffer, std::streamsize length);
	int writeToDevice(const char* buffer, std::streamsize length);

private:
	CHTTPSession&   m_session;
	openmode        m_mode;
	std::streamsize m_chunk;
	std::string     m_chunkBuffer;
};


//
// CHTTPChunkedIOS
//
class CHTTPChunkedIOS : public virtual std::ios
{
public:
	CHTTPChunkedIOS(CHTTPSession& session, CHTTPChunkedStreamBuf::openmode mode);
	~CHTTPChunkedIOS();
	CHTTPChunkedStreamBuf* rdbuf();

protected:
	CHTTPChunkedStreamBuf m_buf;
};


//
// CHTTPChunkedInputStream
//
class CHTTPChunkedInputStream : public CHTTPChunkedIOS, public std::istream
{
public:
	CHTTPChunkedInputStream(CHTTPSession& session);
	~CHTTPChunkedInputStream();

	void* operator new(std::size_t size);
	void operator delete(void* ptr);

private:
	static CMemoryPool m_pool;
};


//
// CHTTPChunkedOutputStream
//
class CHTTPChunkedOutputStream : public CHTTPChunkedIOS, public std::ostream
{
public:
	CHTTPChunkedOutputStream(CHTTPSession& session);
	~CHTTPChunkedOutputStream();

	void* operator new(std::size_t size);
	void operator delete(void* ptr);

private:
	static CMemoryPool m_pool;
};

NET_NAMESPACE_END

#endif
